Backtracing segfaults in a daemon in digitalmars D
Published 2007-01-31 17:41:05
One the projects I'm working on is a SyncML server, written from scratch in D, It's currently in testing mode, and we found that the server was mysteriously crashing. Unfortunatly, since it's threaded, and forked as a daemon, we didn't really want to run it under GDB, (and since GDB segfaults on startup anyway). we where at a bit of a quagmire about how to find the bug.
So after a bit of searching through code.google.com I came across the idea of catching the SIGSEGV signal and calling backtrace and backtrace_symbols
This little trick can product output that looks something like
addr2line can result in some great debugging information.
This is my little backtrace logger for the deamon logger.
So after a bit of searching through code.google.com I came across the idea of catching the SIGSEGV signal and calling backtrace and backtrace_symbols
This little trick can product output that looks something like
/path/to/application [0xAAAAAA] << address of codewhich initially seemed a bit cryptic, but by putting it together with
/path/to/application [0xAAAAAA] << address of code
/path/to/application [0xAAAAAA] << address of code
/path/to/application [0xAAAAAA] << address of code
addr2line can result in some great debugging information.
This is my little backtrace logger for the deamon logger.
static void print_trace()of course you need to use a few C externs to make this work:
{
void *btarray[10];
size_t size;
char **strings;
size_t i;
pid_t pid = getpid();
//writefln("SEG");
size = backtrace(cast(void**)btarray, 10);
strings = backtrace_symbols(cast(void**)btarray, size);
std.process.system("/bin/echo '----BACKTRACE------' " ~
"> /var/log/myproject/backtrace.log");
for(i = 0; i < size; i++) {
char[] line = std.string.toString(strings[i]);
char[][] bits = std.string.split(line, "[");
char[] left = std.string.strip(bits[0]);
if (!left.length) {
continue;
}
// skip lines with ( in them...
if (std.string.find(left,"(") > -1) {
continue;
}
char[] addr = bits[1][2..length-1];
std.process.system("/bin/echo '----" ~ addr
~ "------' >> /var/log/myproject/backtrace.log");
std.process.system("/usr/bin/addr2line -f -e " ~
left ~ " " ~ addr ~ " >> /var/log/myproject/myproject.log");
}
free(strings);
}
extern (C) {and to add it to you application, stick this in main() somewhere
int backtrace(void **__array, int __size);
char** backtrace_symbols(void **__array, int __size);
pid_t getpid();
sighandler_t signal(int signum, sighandler_t handler);
void sigsegv(int sig)
{
// reset the handler.
signal(SIGSEGV, cast(sighandler_t) 0);
print_trace();
// really die
exit(SIGSEGV);
}
}
signal(SIGSEGV, &sigsegv);testing it is quite simple, just do this in D
void testSegfault()Now looking at the debug file, you can work out where it failed...
{
class SegTest {
void test() {}
}
SegTest a;
a.test();
}
----BACKTRACE------I'm sure with some more work, you could get it to log to syslog...
----805e971------ (THIS IS MY OUTPUT CODE)
_D9myproject7cmdLine6daemon11print_traceFZv
init.c/src/myproject/cmdLine/daemon.d:306
----805e46b------
sigsegv
init.c/src/myproject/cmdLine/daemon.d:121
----804db18------ (AND NOW FOR THE LOCATION OF THE SEGFAULT)
_D9myprojectfort7manager7manager7runOptsFZAa
init.c/src/myproject/manager.d:50
----805617a------
_D9myproject10webRequest10webRequest5parseFAaAaKAaZAa
init.c/src/myproject/webRequest.d:89
----8050c3e------
_D9pmyproject14myprojectThread14myprojectThread18dealWithWebRequestFAaAaZv
init.c/src/myproject/myprojectThread.d:331
----80503d0------
_D9myproject14myprojectThread14myprojectThread3runFZi
init.c/src/myproject/myprojectThread.d:111
----8076260------
_D3std6thread6Thread11threadstartUPvZPv
??:0
----a7fd10bd------
??
Mentioned By:
google.com : april (86 referals)
google.com : php daemon (39 referals)
google.com : january (34 referals)
google.com : catch SIGSEGV (32 referals)
google.com : december (28 referals)
google.com : backtrace_symbols addr2line (22 referals)
www.planet-php.net : Planet PHP (18 referals)
google.com : addr2line backtrace_symbols (16 referals)
google.com : catching SIGSEGV (6 referals)
google.com : backtrace_symbols (5 referals)
google.com : Backtracing php (5 referals)
google.com : sigsegv catch (4 referals)
planet.debian.org.hk : Debian HK : Debian @ Hong Kong (3 referals)
google.com : backtracing (3 referals)
google.com : execinfo.h (3 referals)
google.com : feed deamon (3 referals)
google.com : php daemon (3 referals)
google.com : php segfault (3 referals)
google.com : sigsegv string::find (3 referals)
google.com : std.process (3 referals)
google.com : april (86 referals)
google.com : php daemon (39 referals)
google.com : january (34 referals)
google.com : catch SIGSEGV (32 referals)
google.com : december (28 referals)
google.com : backtrace_symbols addr2line (22 referals)
www.planet-php.net : Planet PHP (18 referals)
google.com : addr2line backtrace_symbols (16 referals)
google.com : catching SIGSEGV (6 referals)
google.com : backtrace_symbols (5 referals)
google.com : Backtracing php (5 referals)
google.com : sigsegv catch (4 referals)
planet.debian.org.hk : Debian HK : Debian @ Hong Kong (3 referals)
google.com : backtracing (3 referals)
google.com : execinfo.h (3 referals)
google.com : feed deamon (3 referals)
google.com : php daemon (3 referals)
google.com : php segfault (3 referals)
google.com : sigsegv string::find (3 referals)
google.com : std.process (3 referals)
Follow us
-
- Some thoughts on the language server and its usefulness in the roobuilder
- Roo Builder for Gtk4 moving forward
- Clustered Web Applications - Mysql and File replication
- GitLive - Branching - Merging
- PDO_DataObject Released
- PDO_DataObject is under way
- Mass email Marketing and anti-spam - some of the how-to..
- Hydra - Recruitment done right
Blog Latest
-
Twitter - @Roojs